{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "6bb75e09-4a88-4ddb-a285-74e61d87452e",
   "metadata": {},
   "source": [
    "【1】"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6e0ada7d-2140-4a12-86cb-25207f8bc82f",
   "metadata": {},
   "source": [
    "单数据系列散点图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "6994f6e3-f3ba-4ade-be2f-ae12ba7c3ebc",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'D:\\\\jupyter\\\\散点图.html'"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import json \n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pyecharts.charts import Scatter,Bar\n",
    "from pyecharts.globals import ThemeType\n",
    "from pyecharts import options as opts\n",
    "from pyecharts.commons.utils import JsCode \n",
    "\n",
    "data = pd.read_csv('./data/GLB.Ts+dSST.csv',header=1) # 从指定路径读取文件，并设置第一行为表头\n",
    "\n",
    "# 将数据从宽表转换为长表melt（）  id_vars要保留的列\n",
    "dt = data.iloc[:,:13].melt(id_vars='Year')  # 将前13列数据转换为长表格式\n",
    "maps = dict(zip(data.iloc[:,1:13].columns.tolist(),range(1,13))) # 创建月份映射字典\n",
    "dt['month'] = dt['variable'].map(maps) # 将‘variable’列中的月份名额映射为数字\n",
    "dt['data'] = dt['Year'].astype('str') + '-' + dt['month'].astype('str') # 生成日期字符串\n",
    "dt['data'] = pd.to_datetime(dt['data']).apply(lambda x: x.strftime('%Y-%m'))\n",
    "\n",
    "# 提取日期和温度值\n",
    "data_pair = dt[['data','value']].values.tolist() # 提取‘data’和‘value’列，并转化为列表\n",
    "\n",
    "# 定义标签格式函数\n",
    "label_js = \"\"\"function(params){\n",
    "if (params >= 0){\n",
    "return ('+' + params);\n",
    "} else{return params;}\n",
    "}\n",
    "\"\"\"\n",
    "\n",
    "# 定义一个JavaScript函数，用于格式化y轴标签\n",
    "\n",
    "\n",
    "sca = (Scatter(init_opts=opts.InitOpts(theme=ThemeType.LIGHT,width='980px'))\n",
    "       .add_xaxis([i[0] for i in data_pair])\n",
    "       .add_yaxis(\"温度\",[i[1] for i in data_pair], # 添加y轴的数据\n",
    "                  symbol_size=10, # 设置散点的大小\n",
    "                  itemstyle_opts=opts.ItemStyleOpts(border_width=0.5,opacity=0.5), # 设置项目样式，边框宽度和透明度\n",
    "                  markline_opts=opts.MarkLineOpts(data=[opts.MarkLineItem(y=0)],  # 设置标记线y=0\n",
    "                                                  label_opts=opts.LabelOpts(is_show=False)\n",
    "                                                 )\n",
    "                 )\n",
    "       .set_global_opts(\n",
    "           title_opts=opts.TitleOpts(title='Global Temperate Trends',\n",
    "                                    subtitle='source:nasa giss'),\n",
    "           legend_opts=opts.LegendOpts(is_show=False),\n",
    "           xaxis_opts=opts.AxisOpts(type_='time',   # 设置x轴类型为时间轴\n",
    "                                    split_number=20, # 分割线数量\n",
    "                                    position='bottom', # x轴位置\n",
    "                                    offset=2, # 偏移量\n",
    "                                    splitline_opts=opts.SplitLineOpts(is_show=False),  # 不显示分割线\n",
    "                                    axisline_opts=opts.AxisLineOpts(is_show=False),\n",
    "                                    axistick_opts=opts.AxisTickOpts(is_show=False)\n",
    "                                   ),\n",
    "           yaxis_opts=opts.AxisOpts(type_='value', # 设置y轴类型为数值型\n",
    "                                    min_=-0.8, # y轴最小值\n",
    "                                    max_=1.4, # y轴最大值\n",
    "                                    split_number=10, # 分割线数量\n",
    "                                    name='Anonaly Distance from 1951-1980 average', # y轴名称\n",
    "                                    name_location='center', # 名称位置，类似于柱形图当中pos_left='center'\n",
    "                                    name_gap='40', # 名称与轴线之间的距离\n",
    "                                    splitline_opts=opts.SplitLineOpts(is_show=False),  # 不显示分割线\n",
    "                                    axisline_opts=opts.AxisLineOpts(is_show=False),    # 不显示轴线\n",
    "                                    axistick_opts=opts.AxisTickOpts(is_show=True),     # 显示刻度线再内部\n",
    "                                    axislabel_opts=opts.LabelOpts(is_show=True,   # 显示标签\n",
    "                                                                 formatter=JsCode(label_js))\n",
    "                                   ),\n",
    "           tooltip_opts=opts.TooltipOpts(trigger='item', # 显示框触发方式\n",
    "                                        axis_pointer_type='cross'),\n",
    "           visualmap_opts=opts.VisualMapOpts(is_show=False,  # 不显示视觉映射\n",
    "                                            is_calculable=True, # 可计算\n",
    "                                            range_color=['blue','#c5dbe9','#eab195','#681321','red'], # 颜色范围\n",
    "                                            min_=-0.8,  # 最小值\n",
    "                                            max_=1.2)  # 最大值\n",
    "           \n",
    "       )\n",
    "       .set_series_opts(label_opts=opts.LabelOpts(is_show=False)) # 不显示系列标签\n",
    "      \n",
    "      )\n",
    "sca.render('散点图.html')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8bc37172-c3ed-4313-9a39-2a9772769da0",
   "metadata": {},
   "source": [
    "【2】"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "18c321f7-cb3a-4700-b03e-81427ecefb29",
   "metadata": {},
   "source": [
    "带标签的散点图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "987ca294-5320-4d87-a250-463969d1ad18",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'D:\\\\jupyter\\\\带标签的散点图.html'"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pyecharts.charts import Scatter\n",
    "from pyecharts.globals import ThemeType\n",
    "from pyecharts import options as opts\n",
    "from pyecharts.commons.utils import JsCode\n",
    "\n",
    "data = pd.read_csv('./data/cars.csv')\n",
    "data_pair = data[['name','mpg','hp']].values.tolist()\n",
    "\n",
    "# 定义标签格式化函数\n",
    "label_js = \"\"\"function(params) {\n",
    "console.log(params);\n",
    "return params.data[2];\n",
    "}\"\"\"\n",
    "# 定义提示框格式化函数\n",
    "tooltip_js = \"\"\"function(params) {\n",
    "console.log(params);\n",
    "return (params.data[2] + '<br>燃油效率:' + params.data[0] + '</br>发动机功率:' + params.data[1]);\n",
    "}\"\"\"\n",
    "\n",
    "sca = (\n",
    "    Scatter(init_opts=opts.InitOpts(theme=ThemeType.ESSOS,width='980px'))\n",
    "    .add_xaxis([i[1] for i in data_pair]) # 添加x轴数据（mpg）\n",
    "    .add_yaxis(\n",
    "        'TheCarInfo',\n",
    "        [[i[2],i[0]] for i in data_pair],\n",
    "        symbol_size=7,\n",
    "        label_opts=opts.LabelOpts(formatter=JsCode(label_js),position='right'),\n",
    "        itemstyle_opts=opts.ItemStyleOpts()\n",
    "    )\n",
    "    .set_global_opts(\n",
    "        xaxis_opts=opts.AxisOpts(type_='value', # 设置y轴类型为数值型\n",
    "                                    min_=10, # y轴最小值\n",
    "                                    max_=30, # y轴最大值\n",
    "                                    split_number=12, # 分割线数量\n",
    "                                    name='燃油效率', # y轴名称\n",
    "                                    name_location='center', # 名称位置，类似于柱形图当中pos_left='center'\n",
    "                                    name_gap='36', # 名称与轴线之间的距离\n",
    "                                    splitline_opts=opts.SplitLineOpts(is_show=False),  # 不显示分割线\n",
    "                                    axisline_opts=opts.AxisLineOpts(is_show=False),    # 不显示轴线\n",
    "                                   ),\n",
    "        title_opts=opts.TitleOpts(\n",
    "            title='汽车燃油效率与发动机效率关系标签散点图',\n",
    "            subtitle='The 1974 Motor Trend magazine.'\n",
    "        ),\n",
    "        yaxis_opts=opts.AxisOpts(type_='value', # 设置y轴类型为数值型\n",
    "                                    min_=30, # y轴最小值\n",
    "                                    max_=360, # y轴最大值\n",
    "                                    split_number=10, # 分割线数量\n",
    "                                    name='发动机效率', # y轴名称\n",
    "                                    name_location='center', # 名称位置，类似于柱形图当中pos_left='center'\n",
    "                                    name_gap='36', # 名称与轴线之间的距离\n",
    "                                    axisline_opts=opts.AxisLineOpts(is_show=False),    # 不显示轴线\n",
    "                                   ),\n",
    "        tooltip_opts=opts.TooltipOpts(formatter=JsCode(tooltip_js),\n",
    "                                      trigger='item', # 显示框触发方式\n",
    "                                      axis_pointer_type='line')\n",
    "    )\n",
    ")\n",
    "sca.render('带标签的散点图.html')"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "226c103d-7782-4e1c-a454-ea624a3c8297",
   "metadata": {},
   "source": [
    "【3】"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "50a380dc-ad03-4e0a-ba16-f5f566b933e6",
   "metadata": {},
   "source": [
    "多数据散点图"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "4e1484ac-1401-4a8a-81a0-505c0d1d87f0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "处理后的数据\n",
      "     Month  Average     Peak\n",
      "0  2012-08  15475.0  52261.0\n",
      "1  2012-09  16001.0  36057.0\n",
      "2  2012-10  10739.0  20850.0\n",
      "3  2012-11  14134.0  50533.0\n",
      "4  2012-12  14079.0  27553.0\n",
      "平均在线值统计\n",
      "count       121.000000\n",
      "mean     352008.735537\n",
      "std      210402.835460\n",
      "min       10739.000000\n",
      "25%      239935.000000\n",
      "50%      360926.000000\n",
      "75%      501620.000000\n",
      "max      857591.000000\n",
      "Name: Average, dtype: float64\n",
      "竞赛在线峰值统计\n",
      "count    1.210000e+02\n",
      "mean     6.111063e+05\n",
      "std      3.340546e+05\n",
      "min      2.085000e+04\n",
      "25%      4.260080e+05\n",
      "50%      6.540690e+05\n",
      "75%      8.236940e+05\n",
      "max      1.308110e+06\n",
      "Name: Peak, dtype: float64\n",
      "[['2012-08', 15475.0, 52261.0], ['2012-09', 16001.0, 36057.0], ['2012-10', 10739.0, 20850.0], ['2012-11', 14134.0, 50533.0], ['2012-12', 14079.0, 27553.0], ['2013-01', 16164.0, 31359.0], ['2013-02', 17373.0, 35238.0], ['2013-03', 15960.0, 32166.0], ['2013-04', 16006.0, 31966.0], ['2013-05', 18710.0, 53379.0], ['2013-06', 18120.0, 33700.0], ['2013-07', 20493.0, 42149.0], ['2013-08', 25962.0, 50511.0], ['2013-09', 27679.0, 52052.0], ['2013-10', 27902.0, 53263.0], ['2013-11', 29891.0, 92279.0], ['2013-12', 46788.0, 96298.0], ['2014-01', 55627.0, 102084.0], ['2014-02', 59791.0, 119764.0], ['2014-03', 70143.0, 164495.0], ['2014-04', 78881.0, 142526.0], ['2014-05', 84925.0, 170137.0], ['2014-06', 84164.0, 164134.0], ['2014-07', 106138.0, 193613.0], ['2014-08', 133186.0, 277192.0], ['2014-09', 131035.0, 242494.0], ['2014-10', 133538.0, 260613.0], ['2014-11', 147329.0, 348018.0], ['2014-12', 183590.0, 367634.0], ['2015-01', 234071.0, 443188.0], ['2015-02', 239935.0, 455508.0], ['2015-03', 267996.0, 595439.0], ['2015-04', 291749.0, 568556.0], ['2015-05', 317286.0, 677701.0], ['2015-06', 344156.0, 610401.0], ['2015-07', 329532.0, 541181.0], ['2015-08', 357535.0, 819902.0], ['2015-09', 355905.0, 725939.0], ['2015-10', 362766.0, 732093.0], ['2015-11', 360926.0, 786707.0], ['2015-12', 377447.0, 823694.0], ['2016-01', 365371.0, 667432.0], ['2016-02', 376285.0, 738969.0], ['2016-03', 379427.0, 737599.0], ['2016-04', 375796.0, 850485.0], ['2016-05', 338738.0, 668612.0], ['2016-06', 334311.0, 579110.0], ['2016-07', 353778.0, 636056.0], ['2016-08', 347229.0, 599095.0], ['2016-09', 322526.0, 638360.0], ['2016-10', 333076.0, 661985.0], ['2016-11', 329045.0, 627124.0], ['2016-12', 342196.0, 662460.0], ['2017-01', 393110.0, 814616.0], ['2017-02', 402386.0, 744468.0], ['2017-03', 386909.0, 742356.0], ['2017-04', 392199.0, 709841.0], ['2017-05', 371829.0, 692966.0], ['2017-06', 374388.0, 614621.0], ['2017-07', 377589.0, 624785.0], ['2017-08', 374426.0, 595781.0], ['2017-09', 354402.0, 665371.0], ['2017-10', 341861.0, 639968.0], ['2017-11', 321131.0, 601881.0], ['2017-12', 340877.0, 598405.0], ['2018-01', 382031.0, 715850.0], ['2018-02', 382457.0, 686588.0], ['2018-03', 354270.0, 672502.0], ['2018-04', 289077.0, 523262.0], ['2018-05', 262171.0, 454481.0], ['2018-06', 266862.0, 420261.0], ['2018-07', 273307.0, 426008.0], ['2018-08', 283531.0, 454370.0], ['2018-09', 333164.0, 583029.0], ['2018-10', 325908.0, 565968.0], ['2018-11', 310085.0, 546031.0], ['2018-12', 395509.0, 746548.0], ['2019-01', 386062.0, 587724.0], ['2019-02', 371359.0, 654069.0], ['2019-03', 390240.0, 680071.0], ['2019-04', 351990.0, 621614.0], ['2019-05', 364417.0, 588453.0], ['2019-06', 396994.0, 590309.0], ['2019-07', 397262.0, 578814.0], ['2019-08', 414429.0, 648985.0], ['2019-09', 409797.0, 721288.0], ['2019-10', 407275.0, 749590.0], ['2019-11', 426496.0, 760046.0], ['2019-12', 457289.0, 767683.0], ['2020-01', 497278.0, 814953.0], ['2020-02', 542338.0, 927977.0], ['2020-03', 667176.0, 1135567.0], ['2020-04', 857591.0, 1308110.0], ['2020-05', 769455.0, 1200805.0], ['2020-06', 675266.0, 1021372.0], ['2020-07', 627502.0, 857560.0], ['2020-08', 640278.0, 926005.0], ['2020-09', 607543.0, 973880.0], ['2020-10', 613158.0, 945586.0], ['2020-11', 669347.0, 1037464.0], ['2020-12', 714989.0, 1164396.0], ['2021-01', 741245.0, 1107319.0], ['2021-02', 747527.0, 1123058.0], ['2021-03', 739242.0, 1199606.0], ['2021-04', 718538.0, 1145336.0], ['2021-05', 664665.0, 1080686.0], ['2021-06', 549388.0, 928953.0], ['2021-07', 503920.0, 763228.0], ['2021-08', 501620.0, 803349.0], ['2021-09', 508890.0, 944971.0], ['2021-10', 508122.0, 864643.0], ['2021-11', 541336.0, 938757.0], ['2021-12', 544247.0, 947533.0], ['2022-01', 598065.0, 988969.0], ['2022-02', 634678.0, 997481.0], ['2022-03', 579535.0, 992704.0], ['2022-04', 548253.0, 1016762.0], ['2022-05', 561279.0, 932615.0], ['2022-06', 569542.0, 906968.0], ['2022-07', 592978.0, 927570.0], ['2022-08', 638072.0, 1039161.0]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'D:\\\\jupyter\\\\多数据系列的散点图.html'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "from pyecharts.charts import Scatter\n",
    "from pyecharts.globals import ThemeType\n",
    "from pyecharts import options as opts\n",
    "from pyecharts.commons.utils import JsCode\n",
    "\n",
    "data = pd.read_excel('./data/subject.xlsx')\n",
    "# 提取需要的数据列\n",
    "data_pair = data[['Month','Average','Peak']].copy()\n",
    "\n",
    "# 确保所有数据多少数值类型\n",
    "def to_numeric(value):\n",
    "    try:\n",
    "        return float(value)  # 如果正确则转换为float类型\n",
    "    except ValueError:\n",
    "        return 0.0  # 或者可以选择其他默认值\n",
    "# 处理数据，确保所有数据都是数值类型\n",
    "data_pair['Average'] = data_pair['Average'].apply(to_numeric) # 将Average列转换为浮点型\n",
    "data_pair['Peak'] = data_pair['Peak'].apply(to_numeric)\n",
    "\n",
    "# 去重，如果有重复的月份，则保留第一个出现的行\n",
    "data_pair.drop_duplicates(subset=['Month'],keep='first',inplace=True)\n",
    "\n",
    "# 创建完整的日期范围\n",
    "all_months = pd.date_range(start=data_pair['Month'].min(),end=data_pair['Month'].max(),freq='MS').strftime('%Y-%m') # 生成最小月份到最大月份\n",
    "all_months = [month for month in all_months]  # 将生成的日期范围转换为列表\n",
    "\n",
    "# 重置索引并设置month列为索引\n",
    "data_pair.set_index('Month',inplace=True) # 将month列设置为索引\n",
    "# 索引填充所有月份，并用0填充缺失值\n",
    "data_pair=data_pair.reindex(all_months,fill_value=0).reset_index().rename(columns={'index':'Month'}) # 重新索引并填充缺失值\n",
    "\n",
    "# 打印数据以检查\n",
    "print('处理后的数据')\n",
    "print(data_pair.head())\n",
    "\n",
    "# 检查是否有非零值\n",
    "print('平均在线值统计')\n",
    "print(data_pair['Average'].describe())  # 打印average列的描述性统计信息\n",
    "print('竞赛在线峰值统计')\n",
    "print(data_pair['Peak'].describe())\n",
    "\n",
    "# 转换为列表\n",
    "data_pair = data_pair.values.tolist()\n",
    "print(data_pair)   \n",
    "\n",
    "# 定义样式\n",
    "style_1 = {\n",
    "    \"normal\":{\n",
    "        \"color\":\"#00ca95\",\n",
    "        \"shadowColor\":'rgba(251,251,251,.2)',\n",
    "        \"shadowBlur\":0,\n",
    "        \"shadowOffsetX\":2,\n",
    "        \"shadowOffsetY\":2,\n",
    "        \"width\":2\n",
    "    }\n",
    "}\n",
    "style_2 = {\n",
    "    \"normal\":{\n",
    "        \"color\":\"#FF6984\",\n",
    "        \"shadowColor\":'rgba(251,251,251,.2)',\n",
    "        \"shadowBlur\":0,\n",
    "        \"shadowOffsetX\":2,\n",
    "        \"shadowOffsetY\":2,\n",
    "        \"width\":2\n",
    "    }\n",
    "}\n",
    "\n",
    "sca = (\n",
    "    Scatter(init_opts=opts.InitOpts(theme=ThemeType.LIGHT,bg_color='#080b30'))\n",
    "    .add_xaxis([i[0] for i in data_pair]) # 添加x轴数据\n",
    "    .add_yaxis(\"平均在线\",[i[1]/10000 for i in data_pair], # 添加y轴的数据\n",
    "                  symbol_size=7, # 设置散点的大小\n",
    "                  itemstyle_opts=style_1\n",
    "                 )\n",
    "    .add_yaxis(\"竞赛在线峰值\",[i[2]/10000 for i in data_pair], # 添加y轴的数据\n",
    "                  symbol_size=7, # 设置散点的大小\n",
    "                  itemstyle_opts=style_2,\n",
    "                  symbol='circle' # 使用圆形符号\n",
    "                 )\n",
    "    .set_global_opts(\n",
    "        title_opts=opts.TitleOpts(title='多数据系列散点图'),\n",
    "        tooltip_opts=opts.TooltipOpts(trigger='item', # 显示框触发方式\n",
    "                                      axis_pointer_type='cross'),\n",
    "        xaxis_opts=opts.AxisOpts(type_='category'),\n",
    "        yaxis_opts=opts.AxisOpts(type_='value', # 设置y轴类型为数值型\n",
    "                                    min_=0, # y轴最小值\n",
    "                                    max_=150, # y轴最大值\n",
    "                                    interval=30, # 设置y轴间隔\n",
    "                                    splitline_opts=opts.SplitLineOpts(is_show=True)\n",
    "                                   )\n",
    "    )\n",
    "    .set_series_opts(label_opts=opts.LabelOpts(is_show=False)) # 不显示系列标签\n",
    ")\n",
    "sca.render('多数据系列的散点图.html')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
